package chat;

//================== ChatServer.java ==================
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;

public class ChatServer {
    private static final int PORT = 8888;
    private static final String MESSAGE_HISTORY_DIR = "chat_history/";
    private static final String GROUP_FILES_DIR = "group_files/";

    private ServerSocket serverSocket;
    private Map<String, UserInfo> onlineUsers;
    private Map<String, Set<String>> groupMembers;
    private Map<String, Set<String>> subgroups = new ConcurrentHashMap<>(); // 小组ID -> 成员集合
    private ExecutorService threadPool;
    private boolean running;

    public ChatServer() {
        onlineUsers = new ConcurrentHashMap<>();
        groupMembers = new ConcurrentHashMap<>();
        threadPool = Executors.newCachedThreadPool();

        // 创建目录
        new File(MESSAGE_HISTORY_DIR).mkdirs();
        new File(GROUP_FILES_DIR).mkdirs();
    }

    public void start() {
        try {
            serverSocket = new ServerSocket(PORT);
            running = true;
            System.out.println("聊天室服务器启动，端口: " + PORT);

            while (running) {
                Socket clientSocket = serverSocket.accept();
                threadPool.submit(new ClientHandler(clientSocket));
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
        }
    }

    public void stop() {
        running = false;
        try {
            if (serverSocket != null) serverSocket.close();
            threadPool.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ClientHandler implements Runnable {
        private Socket socket;
        private ObjectInputStream input;
        private ObjectOutputStream output;
        private String username;

        public ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                output = new ObjectOutputStream(socket.getOutputStream());
                input = new ObjectInputStream(socket.getInputStream());

                while (running) {
                    Message message = (Message) input.readObject();
                    handleMessage(message);
                }
            } catch (Exception e) {
                System.out.println("客户端断开连接: " + username);
            } finally {
                cleanup();
            }
        }


        private void handleMessage(Message message) throws IOException {
            switch (message.getType()) {
                case LOGIN:
                    handleLogin(message);
                    break;
                case LOGOUT:
                    handleLogout(message);
                    break;
                case GROUP_CHAT:
                    handleGroupChat(message);
                    break;
                case PRIVATE_CHAT:
                    handlePrivateChat(message);
                    break;
                case FILE_TRANSFER:
                    handleFileTransfer(message);
                    break;
                case GROUP_FILE:
                    handleGroupFile(message);
                    break;
                case IMAGE:
                    handleImageMessage(message);
                    break;
                case SUBGROUP_INVITE:
                    handleSubgroupInvite(message);
                    break;
                case SUBGROUP_ACCEPT:
                    handleSubgroupAccept(message);
                    break;
                case SUBGROUP_REJECT:
                    handleSubgroupReject(message);
                    break;
                case SUBGROUP_CHAT:
                    handleSubgroupChat(message);
                    break;
                case SUBGROUP_LEAVE:
                    handleSubgroupLeave(message);
                    break;
                case GROUP_MEMBER_REQUEST:
                    handleGroupMemberRequest(message);
                    break;
                case HISTORY_REQUEST:
                    handleHistoryRequest(message);
                case IP_UPDATE:
                    String user = message.getSender();
                    String ip = message.getIpAddress();
                    int port = message.getVoicePort();

                    // 验证端口有效性
                    if (port <= 0) {
                        System.err.println("忽略无效端口更新: " + user + " -> " + port);
                        break;
                    }

                    if (user != null && ip != null && onlineUsers.containsKey(user)) {
                        UserInfo userInfo = onlineUsers.get(user);
                        userInfo.setIpAddress(ip);
                        userInfo.setVoicePort(port);

                        // 创建新的IP更新消息，确保所有字段正确
                        Message ipMsg = new Message(Message.Type.IP_UPDATE, user, "");
                        ipMsg.setIpAddress(ip);
                        ipMsg.setVoicePort(port);

                        // 广播给所有其他用户（不包括发送者自己）
                        for (UserInfo receiver : onlineUsers.values()) {
                            if (!receiver.getUsername().equals(user)) {
                                try {
                                    receiver.getOutput().writeObject(ipMsg);
                                } catch (IOException e) {
                                    onlineUsers.remove(receiver.getUsername());
                                }
                            }
                        }
                    }
                    break;
                case IMAGE_DOWNLOAD_REQUEST:
                    handleImageDownloadRequest(message);
                    break;
            }
        }

        // 添加广播IP更新的方法
        private void broadcastIPUpdate(String user, String ip, int port) throws IOException {
            Message ipMsg = new Message(Message.Type.IP_UPDATE, user, "");
            ipMsg.setIpAddress(ip);
            ipMsg.setVoicePort(port);

            for (UserInfo userInfo : onlineUsers.values()) {
                try {
                    userInfo.getOutput().writeObject(ipMsg);
                } catch (IOException e) {
                    // 移除离线用户
                    onlineUsers.remove(userInfo.getUsername());
                }
            }
        }

        private void handleGroupMemberRequest(Message message) throws IOException {
            String group = message.getGroup();
            if (groupMembers.containsKey(group)) {
                // 直接发送当前群成员列表
                sendGroupMemberList(group);
            }
        }

        // 处理群聊消息时发送群成员列表
        private void handleGroupChat(Message message) throws IOException {
            String group = message.getGroup();

            // 检查用户是否是第一次加入这个群组
            boolean isFirstJoin = !groupMembers.containsKey(group) ||
                    !groupMembers.get(group).contains(username);

            // 用户加入群组
            if (!groupMembers.containsKey(group)) {
                groupMembers.put(group, ConcurrentHashMap.newKeySet());
            }
            groupMembers.get(group).add(username);
            onlineUsers.get(username).getGroups().add(group);

            // 如果是第一次加入或重新加入，发送历史消息
            if (isFirstJoin) {
                sendGroupHistory(group, username);
            }

            // 保存消息
            saveMessage(group, message);

            // 广播给群组成员
            for (String member : groupMembers.get(group)) {
                UserInfo memberInfo = onlineUsers.get(member);
                if (memberInfo != null) {
                    try {
                        memberInfo.getOutput().writeObject(message);
                    } catch (IOException e) {
                        onlineUsers.remove(member);
                        groupMembers.get(group).remove(member);
                    }
                }
            }

            // 发送群成员列表
            sendGroupMemberList(group);
        }

        // 发送群成员列表
        private void sendGroupMemberList(String group) throws IOException {
            if (groupMembers.containsKey(group)) {
                Message memberListMsg = new Message(Message.Type.GROUP_MEMBER_LIST,
                        "系统", "群成员列表");
                memberListMsg.setGroup(group);
                memberListMsg.setMemberList(new ArrayList<>(groupMembers.get(group)));

                for (String member : groupMembers.get(group)) {
                    UserInfo memberInfo = onlineUsers.get(member);
                    if (memberInfo != null) {
                        memberInfo.getOutput().writeObject(memberListMsg);
                    }
                }
            }
        }

        // 处理小组邀请
        private void handleSubgroupInvite(Message message) throws IOException {
            String subgroupId = message.getSubgroupId();
            String sender = message.getSender();
            String receiver = message.getReceiver();

            subgroups.computeIfAbsent(subgroupId, k -> ConcurrentHashMap.newKeySet())
                    .add(sender);

            UserInfo receiverInfo = onlineUsers.get(receiver);
            if (receiverInfo != null) {
                receiverInfo.getOutput().writeObject(message);
            }
        }

        // 处理接受小组邀请
        private void handleSubgroupAccept(Message message) throws IOException {
            String subgroupId = message.getSubgroupId();
            String sender = message.getSender();

            // 添加到小组
            subgroups.computeIfAbsent(subgroupId, k -> ConcurrentHashMap.newKeySet())
                    .add(sender);

            // 通知邀请者
            UserInfo inviterInfo = onlineUsers.get(message.getReceiver());
            if (inviterInfo != null) {
                inviterInfo.getOutput().writeObject(message);
            }

            // 通知小组成员
            broadcastToSubgroup(subgroupId, new Message(Message.Type.SUBGROUP_CHAT,
                    "系统", sender + " 加入了小组"));
        }

        private void handleSubgroupReject(Message message) throws IOException {
            String subgroupId = message.getSubgroupId();
            String rejecter = message.getSender();

            // 通知邀请者
            UserInfo inviter = onlineUsers.get(message.getReceiver());
            if (inviter != null) {
                Message notify = new Message(
                        Message.Type.SUBGROUP_CHAT,
                        "系统",
                        rejecter + " 拒绝了小组邀请"
                );
                notify.setSubgroupId(subgroupId);
                inviter.getOutput().writeObject(notify);
            }
        }

        // 处理小组聊天
        private void handleSubgroupChat(Message message) throws IOException {
            String subgroupId = message.getSubgroupId();
            broadcastToSubgroup(subgroupId, message);
        }

        // 处理离开小组
        private void handleSubgroupLeave(Message message) throws IOException {
            String subgroupId = message.getSubgroupId();
            String sender = message.getSender();

            // 从小组中移除
            if (subgroups.containsKey(subgroupId)) {
                subgroups.get(subgroupId).remove(sender);

                // 通知小组成员
                broadcastToSubgroup(subgroupId, new Message(Message.Type.SUBGROUP_CHAT,
                        "系统", sender + " 离开了小组"));
            }
        }

        // 广播消息给小组所有成员
        private void broadcastToSubgroup(String subgroupId, Message message) throws IOException {
            Set<String> members = subgroups.get(subgroupId);
            if (members != null) {
                for (String member : members) {
                    UserInfo memberInfo = onlineUsers.get(member);
                    if (memberInfo != null) {
                        memberInfo.getOutput().writeObject(message);
                    }
                }
            }
        }

        // 新增：图片消息处理
        private void handleImageMessage(Message message) throws IOException {
            // 保存图片到服务器本地
            if (message.getFileData() != null && message.getFileName() != null) {
                File imageDir = new File(MESSAGE_HISTORY_DIR + "images/");
                imageDir.mkdirs();
                File imageFile = new File(imageDir, message.getFileName());
                try (FileOutputStream fos = new FileOutputStream(imageFile)) {
                    fos.write(message.getFileData());
                }
                // 保存历史消息（只保存文件名，不保存二进制数据）
                if (message.getGroup() != null) {
                    saveGroupImageMessage(message.getGroup(), message.getSender(), message.getFileName(), message.getTimestamp());
                } else if (message.getReceiver() != null) {
                    savePrivateImageMessage(message.getSender(), message.getReceiver(), message.getFileName(), message.getTimestamp());
                }
                // 清空fileData，仅保留fileName
                message.setFileData(null);
            }
            // 转发图片消息
            if (message.getGroup() != null) {
                for (String member : groupMembers.getOrDefault(message.getGroup(), new HashSet<>())) {
                    UserInfo memberInfo = onlineUsers.get(member);
                    if (memberInfo != null) {
                        memberInfo.getOutput().writeObject(message);
                    }
                }
            } else if (message.getReceiver() != null) {
                UserInfo receiverInfo = onlineUsers.get(message.getReceiver());
                if (receiverInfo != null) {
                    receiverInfo.getOutput().writeObject(message);
                }
                // 发送给发送者确认
                output.writeObject(message);
            }
        }

        // 保存群聊图片消息到每个在线用户的文件
        private void saveGroupImageMessage(String group, String sender, String fileName, String timestamp) {
            Set<String> groupUsers = groupMembers.get(group);
            if (groupUsers != null) {
                for (String user : groupUsers) {
                    if (onlineUsers.containsKey(user)) {
                        String filePath = MESSAGE_HISTORY_DIR + "user_" + user + "_group_" + group + ".txt";
                        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
                            writer.write(timestamp + " [" + sender + "]: [图片] " + fileName);
                            writer.newLine();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        // 保存私聊图片消息
        private void savePrivateImageMessage(String sender, String receiver, String fileName, String timestamp) {
            String chatId = sender.compareTo(receiver) < 0 ? sender + "_" + receiver : receiver + "_" + sender;
            try {
                File file = new File(MESSAGE_HISTORY_DIR + "private_" + chatId + ".txt");
                try (PrintWriter writer = new PrintWriter(new FileWriter(file, true))) {
                    writer.println(timestamp + " [" + sender + " -> " + receiver + "]: [图片] " + fileName);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private void handleLogout(Message message) {
            cleanup();
        }

        // 保存群聊消息到每个在线用户的文件
        private void saveGroupMessage(String group, Message message) {
            // 获取群组中的所有在线用户
            Set<String> groupUsers = groupMembers.get(group);
            if (groupUsers != null) {
                for (String user : groupUsers) {
                    // 只为在线用户保存消息
                    if (onlineUsers.containsKey(user)) {
                        String filePath = MESSAGE_HISTORY_DIR + "user_" + user + "_group_" + group + ".txt";
                        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
                            writer.write(message.getTimestamp() + " [" + message.getSender() + "]: " + message.getContent());
                            writer.newLine();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        // 加载用户自己的群组历史消息
        private List<Message> loadGroupHistory(String group, String user) {
            List<Message> history = new ArrayList<>();
            File groupFile = new File(MESSAGE_HISTORY_DIR + "user_" + user + "_group_" + group + ".txt");

            if (groupFile.exists()) {
                try (BufferedReader reader = new BufferedReader(new FileReader(groupFile))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        // 解析消息格式: timestamp [sender]: content
                        if (line.contains("]: ")) {
                            String[] parts = line.split("]: ");
                            if (parts.length >= 2) {
                                String timestampAndSender = parts[0];
                                String content = parts[1];
                                int senderStart = timestampAndSender.lastIndexOf(" [") + 2;
                                String timestamp = timestampAndSender.substring(0, senderStart - 2);
                                String sender = timestampAndSender.substring(senderStart);
                                if (content.startsWith("[图片] ")) {
                                    String fileName = content.substring(5);
                                    Message msg = new Message(Message.Type.IMAGE, sender, "[图片]");
                                    msg.setGroup(group);
                                    msg.setTimestamp(timestamp);
                                    msg.setFileName(fileName);
                                    // fileData为null，客户端会自动请求
                                    history.add(msg);
                                } else {
                                    Message msg = new Message(Message.Type.GROUP_CHAT, sender, content);
                                    msg.setGroup(group);
                                    msg.setTimestamp(timestamp);
                                    history.add(msg);
                                }
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return history;
        }

        // 添加解析群组历史消息的方法
        private Message parseGroupHistoryLine(String line, String group) {
            try {
                // 解析格式: "2024-01-01 12:00:00 [username]: message content"
                if (line.contains("]: ")) {
                    String[] parts = line.split("\\]: ", 2);
                    if (parts.length == 2) {
                        String timeAndSender = parts[0];
                        String content = parts[1];

                        // 提取时间戳和发送者
                        int lastBracket = timeAndSender.lastIndexOf('[');
                        if (lastBracket != -1) {
                            String timestamp = timeAndSender.substring(0, lastBracket - 1);
                            String sender = timeAndSender.substring(lastBracket + 1);

                            Message msg = new Message(Message.Type.GROUP_CHAT, sender, content);
                            msg.setTimestamp(timestamp);
                            msg.setGroup(group);
                            return msg;
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略解析错误
            }
            return null;
        }

        // 添加发送群组历史消息的方法
        private void sendGroupHistory(String group, String user) throws IOException {
            List<Message> history = loadGroupHistory(group,username);
            UserInfo userInfo = onlineUsers.get(user);
            if (userInfo != null) {
                for (Message msg : history) {
                    userInfo.getOutput().writeObject(msg);
                }
            }
        }

        // 发送群聊历史消息
        private void sendGroupHistoryMessages(String user) throws IOException {
            UserInfo userInfo = onlineUsers.get(user);
            if (userInfo != null) {
                Set<String> groups = userInfo.getGroups();
                for (String group : groups) {
                    List<Message> history = loadGroupHistory(group,username);
                    for (Message msg : history) {
                        userInfo.getOutput().writeObject(msg);
                    }
                }
            }
        }

        // 处理用户登录
        private void handleLogin(Message message) throws IOException {
            String newUsername = message.getSender();

            // 检查用户漫游 - 踢掉原来的连接
            if (onlineUsers.containsKey(newUsername)) {
                UserInfo existingUser = onlineUsers.get(newUsername);
                Message kickMsg = new Message(Message.Type.KICK_USER, "系统", "您的账号在其他地方登录");
                try {
                    existingUser.getOutput().writeObject(kickMsg);
                    existingUser.getOutput().close();
                } catch (IOException e) {
                    // 忽略关闭异常
                }
            }

            this.username = newUsername;
            UserInfo userInfo = new UserInfo(username, output);
            onlineUsers.put(username, userInfo);

            // 发送登录成功消息
            Message response = new Message(Message.Type.LOGIN, "系统", "登录成功");
            output.writeObject(response);

            // 发送历史消息
            sendHistoryMessages(username);
            sendGroupHistoryMessages(username);

            // 更新用户列表
            broadcastUserList();
            // 发送所有在线用户的IP地址给新登录的用户!!!
            sendAllUserIPs(username);

            System.out.println("用户登录: " + username);
        }

        // 添加发送所有用户IP的方法!!!
        private void sendAllUserIPs(String newUser) throws IOException {
            UserInfo newUserInfo = onlineUsers.get(newUser);
            if (newUserInfo == null) return;

            for (Map.Entry<String, UserInfo> entry : onlineUsers.entrySet()) {
                String user = entry.getKey();
                UserInfo info = entry.getValue();

                // 不发送自己的IP
                if (!user.equals(newUser) && info.getIpAddress() != null) {
                    Message ipMsg = new Message(Message.Type.IP_UPDATE, user, "");
                    ipMsg.setIpAddress(info.getIpAddress());
                    ipMsg.setVoicePort(info.getVoicePort()); // 确保发送端口信息
                    newUserInfo.getOutput().writeObject(ipMsg);
                    System.out.println("发送用户 " + user + " 的IP信息给新用户 " + newUser);
                }
            }
        }

        private void handlePrivateChat(Message message) throws IOException {
            String receiver = message.getReceiver();
            UserInfo receiverInfo = onlineUsers.get(receiver);

            // 保存消息（包括发送者和接收者的记录）
            savePrivateMessage(username, receiver, message);

            if (receiverInfo != null) {
                try {
                    receiverInfo.getOutput().writeObject(message);
                } catch (IOException e) {
                    onlineUsers.remove(receiver);
                }
            }

            // 发送给发送者确认
            output.writeObject(message);
        }

        private void handleFileTransfer(Message message) throws IOException {
            String receiver = message.getReceiver();
            UserInfo receiverInfo = onlineUsers.get(receiver);

            if (receiverInfo != null) {
                try {
                    receiverInfo.getOutput().writeObject(message);
                } catch (IOException e) {
                    onlineUsers.remove(receiver);
                }
            }
        }

        private void handleGroupFile(Message message) throws IOException {
            String group = message.getGroup();
            String sender = message.getSender(); // 记录发送者
            // 保存群文件
            saveGroupFile(group, message.getFileName(), message.getFileData());

            // 通知群成员
            if (groupMembers.containsKey(group)) {
                for (String member : groupMembers.get(group)) {
                    // 跳过消息发送者
                    if (member.equals(sender)) {
                        continue;
                    }

                    UserInfo memberInfo = onlineUsers.get(member);
                    if (memberInfo != null) {
                        try {
                            memberInfo.getOutput().writeObject(message);
                        } catch (IOException e) {
                            onlineUsers.remove(member);
                            groupMembers.get(group).remove(member);
                        }
                    }
                }
            }
        }

        private void handleHistoryRequest(Message message) throws IOException {
            sendHistoryMessages(username);
        }

        private void sendHistoryMessages(String user) throws IOException {
            List<Message> history = loadUserHistory(user);
            for (Message msg : history) {
                output.writeObject(msg);
            }
        }

        private void broadcastUserList() {
            Message userListMsg = new Message(Message.Type.USER_LIST_UPDATE, "系统",
                    String.join(",", onlineUsers.keySet()));

            Iterator<Map.Entry<String, UserInfo>> iterator = onlineUsers.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, UserInfo> entry = iterator.next();
                try {
                    entry.getValue().getOutput().writeObject(userListMsg);
                } catch (IOException e) {
                    iterator.remove();
                }
            }
        }

        private void savePrivateMessage(String sender, String receiver, Message message) {
            String chatId = sender.compareTo(receiver) < 0 ? sender + "_" + receiver : receiver + "_" + sender;

            try {
                File file = new File(MESSAGE_HISTORY_DIR + "private_" + chatId + ".txt");
                try (PrintWriter writer = new PrintWriter(new FileWriter(file, true))) {
                    writer.println(message.getTimestamp() + " [" + sender + " -> " + receiver + "]: " + message.getContent());
                }

                // 不再调用 saveToUserHistory，避免重复保存
                // saveToUserHistory(sender, message);
                // saveToUserHistory(receiver, message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private void saveMessage(String group, Message message) {
            // 不再保存统一的群聊文件
            // 只为在线的群成员保存消息到各自的文件中
            Set<String> groupUsers = groupMembers.get(group);
            if (groupUsers != null) {
                for (String user : groupUsers) {
                    // 只为在线用户保存消息
                    if (onlineUsers.containsKey(user)) {
                        String filePath = MESSAGE_HISTORY_DIR + "user_" + user + "_group_" + group + ".txt";
                        try {
                            File file = new File(filePath);
                            try (PrintWriter writer = new PrintWriter(new FileWriter(file, true))) {
                                writer.println(message.getTimestamp() + " [" + message.getSender() + "]: " + message.getContent());
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        private void saveToUserHistory(String user, Message message) {
            try {
                File file = new File(MESSAGE_HISTORY_DIR + "user_" + user + ".txt");
                try (PrintWriter writer = new PrintWriter(new FileWriter(file, true))) {
                    String prefix = message.getType() == Message.Type.GROUP_CHAT ?
                            "[群:" + message.getGroup() + "] " : "[私聊] ";
                    writer.println(message.getTimestamp() + " " + prefix +
                            message.getSender() + ": " + message.getContent());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private List<Message> loadUserHistory(String user) {
            List<Message> history = new ArrayList<>();

            // 加载私聊记录
            for (Map.Entry<String, UserInfo> entry : onlineUsers.entrySet()) {
                String otherUser = entry.getKey();
                if (!otherUser.equals(user)) {
                    String chatId = user.compareTo(otherUser) < 0 ? user + "_" + otherUser : otherUser + "_" + user;
                    File file = new File(MESSAGE_HISTORY_DIR + "private_" + chatId + ".txt");
                    if (file.exists()) {
                        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                            String line;
                            while ((line = reader.readLine()) != null) {
                                // 解析私聊消息格式: timestamp [sender -> receiver]: content
                                if (line.contains(" -> ")) {
                                    String[] parts = line.split("]: ");
                                    if (parts.length >= 2) {
                                        String timestampAndSender = parts[0];
                                        String content = parts[1];

                                        int senderStart = timestampAndSender.lastIndexOf(" [") + 2;
                                        String timestamp = timestampAndSender.substring(0, senderStart - 2);
                                        String senderInfo = timestampAndSender.substring(senderStart);
                                        String sender = senderInfo.split(" -> ")[0];
                                        String receiver = senderInfo.split(" -> ")[1];

                                        if (content.startsWith("[图片] ")) {
                                            String fileName = content.substring(5);
                                            Message msg = new Message(Message.Type.IMAGE, sender, "[图片]");
                                            msg.setReceiver(receiver);
                                            msg.setTimestamp(timestamp);
                                            msg.setFileName(fileName);
                                            history.add(msg);
                                        } else {
                                            Message msg = new Message(Message.Type.PRIVATE_CHAT, sender, content);
                                            msg.setReceiver(receiver);
                                            msg.setTimestamp(timestamp);
                                            history.add(msg);
                                        }
                                    }
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            // 加载用户自己的群聊记录
            for (Map.Entry<String, Set<String>> entry : groupMembers.entrySet()) {
                String group = entry.getKey();
                if (entry.getValue().contains(user)) {
                    String filePath = MESSAGE_HISTORY_DIR + "user_" + user + "_group_" + group + ".txt";
                    File groupFile = new File(filePath);

                    if (groupFile.exists()) {
                        try (BufferedReader reader = new BufferedReader(new FileReader(groupFile))) {
                            String line;
                            while ((line = reader.readLine()) != null) {
                                // 解析群聊消息格式: timestamp [sender]: content
                                String[] parts = line.split("\\]: ");
                                if (parts.length >= 2) {
                                    String timestampAndSender = parts[0];
                                    String content = parts[1];

                                    int senderStart = timestampAndSender.lastIndexOf(" [") + 2;
                                    String timestamp = timestampAndSender.substring(0, senderStart - 2);
                                    String sender = timestampAndSender.substring(senderStart);

                                    Message msg = new Message(Message.Type.GROUP_CHAT, sender, content);
                                    msg.setGroup(group);
                                    msg.setTimestamp(timestamp);
                                    history.add(msg);
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            return history;
        }

        private Message parseHistoryLine(String line) {
            try {
                if (line.contains("]:")) {
                    String[] parts = line.split("\\]: ", 2);
                    if (parts.length == 2) {
                        String timeAndSender = parts[0];
                        String content = parts[1];

                        // 提取发送者
                        int lastBracket = timeAndSender.lastIndexOf('[');
                        if (lastBracket != -1) {
                            String sender = timeAndSender.substring(lastBracket + 1);
                            Message msg = new Message(Message.Type.GROUP_CHAT, sender, content);
                            return msg;
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略解析错误
            }
            return null;
        }

        private void saveGroupFile(String group, String fileName, byte[] fileData) {
            try {
                File groupDir = new File(GROUP_FILES_DIR + group);
                groupDir.mkdirs();

                File file = new File(groupDir, fileName);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(fileData);
                }
                System.out.println("群文件保存: " + group + "/" + fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private void cleanup() {
            if (username != null) {
                onlineUsers.remove(username);

                // 从所有群组中移除用户
                for (Set<String> members : groupMembers.values()) {
                    members.remove(username);
                }

                broadcastUserList();
                System.out.println("用户离线: " + username);
            }

            try {
                if (socket != null) socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 新增图片下载请求处理
        private void handleImageDownloadRequest(Message message) throws IOException {
            String fileName = message.getContent();
            File imgFile = new File(MESSAGE_HISTORY_DIR + "images/" + fileName);
            if (imgFile.exists()) {
                byte[] data = java.nio.file.Files.readAllBytes(imgFile.toPath());
                Message resp = new Message(Message.Type.IMAGE_DOWNLOAD_RESPONSE, "系统", "[图片]");
                resp.setFileName(fileName);
                resp.setFileData(data);
                UserInfo userInfo = onlineUsers.get(message.getSender());
                if (userInfo != null) {
                    userInfo.getOutput().writeObject(resp);
                }
            }
        }
    }

    public static void main(String[] args) {
        ChatServer server = new ChatServer();
        Runtime.getRuntime().addShutdownHook(new Thread(server::stop));
        server.start();
    }
}